package service

import (
	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/gtcp"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
	"time"
	"yunAIYI_nginxUpdate/app/util"
)

var (
	httpapi_ip   = ""
	httpapi_port = ""
	Sign_key     = ""
)
var ctx = gctx.New()

func init() {
	httpapi_ip = util.GetYunserverIP()

	httpapi_port = util.GetPort_server()
	Sign_key = util.Get_sign_key()
}

// 向服务器注册动态ip
func Registe() {
	ip := util.GetThisServerIP()
	g.Log().Line().Debug(ctx, "开始注册最新公网ip....start,当前pc ip="+ip)

	timestamp := gconv.String(gtime.Now().Timestamp())
	sign, _ := gmd5.EncryptString(ip + timestamp + Sign_key)
	url := "http://" + httpapi_ip + ":" + httpapi_port + "/UpdateIP?nowip=" + ip + "&timestamp=" + timestamp + "&sign=" + sign
	g.Log().Line().Debug(ctx, "接口地址:", url)
	content := g.Client().GetContent(ctx, url)
	g.Log().Line().Debug(ctx, " 接口返回数据:", content)
	if gstr.Contains(content, "success") {
		g.Log().Line().Debug(ctx, "更新云服务器端最新动态公网ip成功!")
		return
	} else {
		g.Log().Line().Debug(ctx, "注册失败，递归注册!")
		time.Sleep(3 * time.Second)
		Registe()
	}
}

// todo: 发现现象：链接正常情况下，心跳正常，但是没有心跳日志，也没有报错！。。。。
// todo: 排查正常情况下会不会 close了 有检测情况没有处理
func TcpServer() {
	//开启本地端口 tcp
	// 任何客户端都可以连上来，会自动断开，但是会触发ip注册和更新机制，所以这里链接时候要有认证，才可以建立链接。
	// 已处理安全问题：白名单机制
	gtcp.NewServer(":"+gconv.String(util.Get_tcp_port()), func(conn *gtcp.Conn) {
		defer conn.Close()

		g.Log().Line().Debug(ctx, "*********************有nginx服务器作为tcp客户端链接：", conn.RemoteAddr().String())
		remoteip := conn.RemoteAddr()
		g.Log().Line().Debug(ctx, "one client connect remoteip -> "+remoteip.String())
		//确保只有指定ip服务器链接才通过
		if gstr.Contains(remoteip.String(), httpapi_ip) {
			g.Log().Line().Debug(ctx, "成功和云服务建立长连接! "+remoteip.String())
			run1 := true
			for run1 {
				data, err := conn.Recv(-1)
				if err != nil {
					g.Log().Line().Debug(ctx, "客户端断开链接", err)
					run1 = false
				} else {
					if len(data) > 0 {
						g.Log().Line().Debug(ctx, "tcpServer get -> ", string(data))
						//监听到有客户端输入信息
						if err := conn.Send([]byte("dynamicIpPc time=" + gtime.Datetime())); err != nil {
							g.Log().Line().Debug(ctx, "有客户端发送来消息但是回话失败", err)
							run1 = false
						} else {
						}
					}
				}
			}
			if !run1 {
				g.Log().Line().Debug(ctx, "需要发起一次向nginx服务器注册最新ip的请求!")
				go Registe()
			}
			g.Log().Line().Debug(ctx, "tcpServer端停止for循环了,因为上个ip已经变化了,开始建立监听新的连接!")
		} else {
			g.Log().Line().Debug(ctx, "有非法ip尝试建立长连接，拒绝请求！"+remoteip.String())
			//执行第一行close
		}
		g.Log().Line().Debug(ctx, "tcp 中断。")

	}).Run()
}
